/* 
    Simple directory viewer
*/
var peerscape = null;
var app = function() {
    return {
        _debug: true,
        _loaded: false,
        // sorting constants
        SORTING_NAME_ASC: 1,
        SORTING_NAME_DSC: 2,
        SORTING_CREATED_ASC: 3,
        SORTING_CREATED_DSC: 4,

        entriesIndexName: null,
        entriesIndexNameDsc: null,
        entriesIndexDate: null,
        entriesIndexDateAsc: null,

        _setup: function() {
            if (app.util.isAdmin(peerscape.contentInfo)) {
                // nothing
            }
        },
        init: function() {
            app.util._get_peerscape();

            // init the error dialog
            app.error.init();

            // show loading anim
            app.loading.init();
            app.loading.show();

            // call _setup
            app._setup();

            // init the main view
            app.home.init();
        },
        postInit: function() {
            $.historyInit(app.historyHandler);
            app._loaded = true;
        },
        load: function(hash) {
            $.historyLoad(hash);
        },
        historyHandler: function(hash) {
            if (hash && hash == 'noop') {
                return false;
            }

            /* this is some kind of bug in safari */
            if ($.browser.safari) {
                if (hash == '' && app._loaded) {
                    return false;
                }
                if (hash == '' && !app._loaded) {
                    app.load('home');
                    return false;
                }
            }

            if (app.curScreen != hash) {
                if (!hash || hash.indexOf('home') == 0) {
                    var page = ((hash && hash.indexOf(':') != -1) ? hash.split(':') : 1);
                    if (!page || page == undefined) {
                        page = 1;
                    }
                    else if (page != 1) {
                        page = page[1];
                    }

                    app.home.curPage = page;
                    app.home.refresh(true);
                    app.home.show();
                    peerscape.common.scrollToTop();
                }
                app.curScreen = hash;
            }
        },
        hideAll: function() {
            app.home.poll.stop();
            for (var s in app.screens) {
                app.screens[s].hide();
            }
        },
        fetchEntries: function(successF, errorF) {
            $.ajax({
                type: 'GET',
                url: '/getall/people?dict=true&json=true',
                success: successF,
                error: errorF
            });
        },
        error: {
            init: function() {
                $('#error .ok a').eq(0)
                    .bind('click', function() {
                        app.error.clear();
                        app.loading.hide();
                        return false;
                    });
            },
            set: function(msg) {
                $('#error').show().find('p.message').html(msg);
            },
            clear: function() {
                $('#error').hide().find('p.message').html('');
            }
        },
        _processEntriesData: function(data) {
            // create indexes to sort by name and created date
            app.entriesIndexName = [];
            app.entriesIndexDate = [];
            for (var e in data) {
                app.entriesIndexName.push(e);
                app.entriesIndexDate.push(e);
            }
            app.entriesIndexDate.sort(function(a, b) {
                if (data[a].created < data[b].created) {
                    return 1;
                }
                else if (data[a].created > data[b].created) {
                    return -1;
                }
                else {
                    return 0;
                }
            });
            app.entriesIndexDateAsc = app.entriesIndexDate.slice(0); // clone array
            app.entriesIndexDateAsc.reverse();
            
            app.entriesIndexName.sort(function(a, b) {
                if (data[a].name.toLowerCase() > data[b].name.toLowerCase()) {
                    return 1;
                }
                else if (data[a].name.toLowerCase() < data[b].name.toLowerCase()) {
                    return -1;
                }
                else {
                    return 0;
                }
            });
            app.entriesIndexNameDsc = app.entriesIndexName.slice(0); // clone array
            app.entriesIndexNameDsc.reverse();

            return data;
        },
        /* -------------- HOME ---------------- */
        home: {
            ITEM_TEMPLATE: null,
            PAGER_ITEM_TEMPLATE: null,

            ITEMS_PER_PAGE: 20,

            curPage: 1,
            numPages: 1,
            lastMark: 0,
            sorting: 4, //SORTING_CREATED_DSC
            init: function() {
                // get the entry template
                app.home.ITEM_TEMPLATE = $('#itemTemplate').clone();
                app.home.ITEM_TEMPLATE.removeAttr('id');

                // add sorting to the header template
                $('#headerTemplate')
                    .find('th.name').eq(0)
                    .wrapInner('<a href="#" class="sorting'+app.home.sorting+'"></a>')
                    .unbind('click')
                    .bind('click', function() {
                        if (app.home.sorting == app.SORTING_NAME_ASC) {
                            app.home.sorting = app.SORTING_NAME_DSC;
                        }
                        else {
                            app.home.sorting = app.SORTING_NAME_ASC;
                        }
                        
                        // set the class
                        $('#headerTemplate th.created').removeAttr('class').attr('class', 'created');
                        $('#headerTemplate th.name').attr('class', 'name sorting'+app.home.sorting);
                        
                        // go to page 1
                        app.home.curPage = 1;

                        // redraw table using
                        app.home.render();

                        return false;
                    });
                $('#headerTemplate')
                    .find('th.created').eq(0)
                    .wrapInner('<a href="#"></a>')
                    .unbind('click')
                    .bind('click', function() {
                        if (app.home.sorting == app.SORTING_CREATED_DSC) {
                            app.home.sorting = app.SORTING_CREATED_ASC;
                        }
                        else {
                            app.home.sorting = app.SORTING_CREATED_DSC;
                        }
                        
                        // set the class
                        $('#headerTemplate th.name').removeAttr('class').attr('class', 'name');
                        $('#headerTemplate th.created').attr('class', 'created sorting'+app.home.sorting);

                        // go to page 1
                        app.home.curPage = 1;

                        // redraw table using
                        app.home.render();

                        return false;
                    });

                // set the class initially
                $('#headerTemplate th.created').attr('class', 'created sorting'+app.home.sorting);

                // get the pager item template
                app.home.PAGER_ITEM_TEMPLATE = $('.pager .template').eq(0).clone();
                app.home.PAGER_ITEM_TEMPLATE.removeAttr('class');

                // set the title
                app.home.setTitle(peerscape.contentInfo.title);
            },
            setTitle: function(t) {
                $('.mainTitle').html(t);
            },
            refresh: function(bHard) {
                app.home.poll.stop();

                app.loading.show();
                if (bHard) {
                    // fetch the entries
                    app.fetchEntries(
                        function(data) {
                            app.entries = app._processEntriesData(eval('(' + data + ')'));
                            app.home.render();
                            app.loading.hide();
                            ++app.home.lastMark;
                        },
                        function (xhr, textStatus, errorThrown) {
                            if (xhr.status == 404) {
                                app.error.set('Message information not found.');
                            }
                            else {
                                app.error.set('');
                            }
                        }
                    );
                }
                else {
                    app.home.render();
                    app.loading.hide();
                }
            },
            removeAll: function() {
                $('#items').empty();
            },
            render: function() {
                if (app.entriesIndexName.length > 0) {
                    $('.inner #none').hide();

                    app.home.removeAll();

                    // get the appropriate index
                    var index = app.entriesIndexName;
                    if (app.home.sorting == app.SORTING_NAME_DSC) {
                        index = app.entriesIndexNameDsc;
                    }
                    else if (app.home.sorting == app.SORTING_CREATED_ASC) {
                        index = app.entriesIndexDateAsc;
                    }
                    else if (app.home.sorting == app.SORTING_CREATED_DSC) {
                        index = app.entriesIndexDate;
                    }

                    var starti = (app.home.curPage - 1) * app.home.ITEMS_PER_PAGE;
                    var endi = starti + app.home.ITEMS_PER_PAGE;
                    if (endi > index.length) {
                        endi = index.length;
                    }
                    for (var e=starti; e<endi; e++) {
                        if (app.entries[index[e]]) {
                            var row = app.home.ITEM_TEMPLATE.clone();
                            row.attr('class', 'item');

                            app.home._renderItem(row, app.entries[index[e]], index[e]);

                            // add item to list
                            $('#items').append(row);
                        }
                    }
                    peerscape.common.resize();
                }
                else {
                    app.home.removeAll();
                    $('#none').show();
                }
                app.home.renderPager();

                app.home.poll.start();
            },
            _renderItem: function(item, entry, path) {
                item.attr('id', entry.id);

                // populate item
                var href = path.substr(8);
                href = 'http://' + href + '.hexlabel.net/';
                item.find('.name a').eq(0)
                    .attr('href', href)
                    .html(entry.name)

                item.find('.created').eq(0)
                    .html(app.util.formatTimestamp(entry.created, true));

            },
            renderPager: function() {
                if (!app.entries || app.entriesIndexName.length == 0) {
                    $('.pager').hide();
                    return;
                }
                
                app.home.numPages = Math.ceil(app.entriesIndexName.length / app.home.ITEMS_PER_PAGE);
                if (app.home.numPages == 1) {
                    $('.pager').hide();
                    return;
                }
                
                $('.pager p span').html(app.home.curPage + '/' + app.home.numPages);

                // insert pager
                $('.pager ul').empty();
                for (var p=1; p<=app.home.numPages; p++) {
                    var item = app.home.PAGER_ITEM_TEMPLATE.clone();
                    app.home._renderPagerItem(item, p);
                    $('.pager ul').append(item);
                }

                $('.pager').show();
            },
            _renderPagerItem: function(item, p) {
                item.find('a').eq(0)
                    .attr('href', '#home:' + p)
                    .html(p)
                    .bind('click', function() {
                        app.load('home:' + p);
                        return false;
                    });

                // select current page link
                if (p == app.home.curPage) {
                    item.find('a').attr('class', 'selected');
                }
            },
            poll: {
                DELAY_MS: 30000,
                id: null,
                start: function() {
                    app.home.poll.id = setTimeout(app.home.poll.tick, app.home.poll.DELAY_MS);
                },
                stop: function() {
                    clearTimeout(app.home.poll.id);
                },
                tick: function() {
                    app.home.refresh(true);
                }
            },
            hide: function() {
                app.home.poll.stop();
                $('#mainList').hide();
            },
            show: function() {
                $('#mainList').show();
                peerscape.common.resize();
            }
        },
        /* -------------- LOADING ---------------- */
        loading: {
            init: function() {
                //app.screens['loading'] = $('#loading');
                app.loading.hide();
            },
            hide: function() {
                $('#loading').hide();
            },
            show: function() {
                $('#loading').show();
                peerscape.common.resize();
            }
        },
        /* -------------- UTIL ---------------- */
        util: {
            WS_RE: /^\s*$/,
            IMAGE_RE: /(\.jpg|\.jpeg|\.png|\.gif)$/i,
            log: function(s) {
                if (!app._debug) {
                    return;
                }
                try {
                    if (console != undefined) {
                        console.log(s);
                    }
                }
                catch(e) { /* nothing */ }
            },
            isEmpty: function(s) {
                return (!s || s.match(app.util.WS_RE));
            },
            isImage: function(s) {
                return (s && s.match(app.util.IMAGE_RE));
            },
            getTimestamp: function() {
                var now = new Date();
                yyyy = now.getUTCFullYear();
                mm = now.getUTCMonth();
                ++mm;
                if (mm <= 9) {
                    mm = '0' + mm;
                }
                dd = now.getUTCDate();
                if (dd <= 9) {
                    dd = '0' + dd;
                }
                hh = now.getUTCHours();
                if (hh <= 9) {
                    hh = '0' + hh;
                }
                mi = now.getUTCMinutes();
                if (mi <= 9) {
                    mi = '0' + mi;
                }
                ss = now.getUTCSeconds();
                if (ss <= 9) {
                    ss = '0' + ss;
                }
                return now.getUTCFullYear()+'-'+mm+'-'+dd+'T'+hh+':'+mi+':'+ss+'Z';
            },
            TS_RE: /(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/,
            formatTimestamp: function(t, brk) {
                // 2009-11-26T14:3:35Z
                var months = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
                var parts = t.match(app.util.TS_RE);

                // this will create a date with local time offset
                var d = new Date(Date.UTC(parts[1], parseInt(parts[2], 10)-1, parts[3], parts[4], parts[5], parts[6], 00))

                // get the 'pretty' representation
                var pretty = (brk ? ' <br/>' : ' ');
                prettyTmp = prettyDate(d.getFullYear()+'-'+(parseInt(d.getMonth()) + 1)+'-'+d.getDate()+'T'+d.getHours()+':'+d.getMinutes()+':00');
                if (prettyTmp != undefined) {
                    pretty += '(' + prettyTmp + ')';
                }
                else {
                    pretty = '';
                }

                // return in local format
                return d.toLocaleString() + pretty;
            },
            nl2br: function(s) {
                return s.replace(/\n/g, '<br/>');
            },
            selectTabNav: function(id) {
                $('#tabNav li').each(function() { $(this).removeAttr('class'); });
                $('#tabNav li#'+id).attr('class', 'selected');
            },
            imageLoader: function(id, src, target) {
                if (app.entriesCache && app.entriesCache[id]) {
                    //cache hit
                    target.attr('src', src).removeAttr('class');
                    peerscape.common.resize();
                }
                else {
                    var img = new Image();
                    img.src = src;
                    img.onload = function() {
                        target.attr('src', src).removeAttr('class');
                        peerscape.common.resize();
                    }
                    // damned opera
                    if ($.browser.opera) {
                        target.attr('src', src);
                        target.removeAttr('class');
                        peerscape.common.resize();
                    }
                }
            },
            _uidpart: function () {
                return(((1+Math.random())*0x10000)|0).toString(16).substring(1);
            },
            generateUID: function(iid) {
                var p = iid.substr(0,8)+'-'+iid.substr(8,4)+'-'+iid.substr(12,4)+'-'+iid.substr(16,4)+'-';
		        return (p+app.util._uidpart()+app.util._uidpart()+app.util._uidpart());
            },
            _get_peerscape: function() {
                try {
                    peerscape = parent.peerscape; 
                }
                catch (e) {
                    peerscape = null;
                }
                if (!peerscape) {
                    peerscape = {
                        contentInfo: {
                            parent_profile: {},
                            owner: {},
                            viewer: {},
                            application: {}
                        },
                        common: {
                            resize: function() {}
                        }
                    }
                }
            },
            /* FIXME: can we make this more comaptible with atom? */
            generateJSONRedirFeed: function(metadata, path) {
                if (!metadata) {
                    metadata = app.metadata;
                }
                var feed = {
                    title: metadata.title,
                    link: {
                        rel: 'self',
                        href: 'http://' + metadata.id + '.hexlabel.net/get/content/feed.json'
                    },
                    id: metadata.id,
                    updated: metadata.updated,
                    generator: {
                        uri: metadata.generator.uri,
                        name: metadata.generator.name
                    },
                    entries: [],
                    peerscape_redir: path
                }
                return feed;
            },
            generateJSONFeed: function(metadata) {
                if (!metadata) {
                    metadata = app.metadata;
                }
                var feed = {
                    title: metadata.title,
                    link: {
                        rel: 'self',
                        href: 'http://' + metadata.id + '.hexlabel.net/get/content/feed.json'
                    },
                    id: metadata.id,
                    updated: metadata.updated,
                    generator: {
                        uri: metadata.generator.uri,
                        name: metadata.generator.name
                    },
                    entries: []
                }
                for (var e in app.entries) {
                    var entry = {
                        title: app.entries[e].title,
                        id: app.entries[e].id,
                        published: app.entries[e].created,
                        updated: app.entries[e].updated,
                        summary: app.entries[e].summary,
                        content: {
                            type: 'text',
                            value: app.entries[e].content
                        },
                        author: {
                            name: app.entries[e].author.name,
                            uri: 'http://'+app.entries[e].author.iid+'.hexlabel.net/'
                        }
                    };
                    feed.entries.push(entry);
                }
                return feed;
            },
            /*
            generateXMLFeed: function() {
                return '<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom"></feed>';
            },
            */
            getImageType: function(src) {
                var ext = src.substr(src.lastIndexOf('.')+1);
                if (ext == 'jpg') {
                    ext = 'jpeg';
                }
                return 'image/'+ext;
            },
            isGroup: function(info) {
                return (info.parent_profile.type == 'group');
            },
            isAdmin: function(info) {
                // view is owner
                if (info.owner.iid == info.viewer.iid) {
                    return true;
                }

                // viewer is group admin
                if (info.parent_profile.type == 'group' && info.viewer.is_group_member) {
                    for (var r in info.viewer.group_roles) {
                        if (info.viewer.group_roles[r] == 'admin') {
                            return true;
                        }
                    }
                }

                // not an admin
                return false;
            }
        }
    }
}();
$(function() {
    app.init();
    app.postInit();
});


